home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / Xpm / pixmap / Handlers.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  21KB  |  749 lines

  1. /* * Last edited: Oct 14 17:28 1991 (mallet) */
  2. /*
  3.  * $Id: Handlers.c,v 1.3 1992/10/27 08:34:07 mallet Exp $
  4.  * 
  5.  * Copyright 1991 Lionel Mallet
  6.  * 
  7.  * Permission to use, copy, modify, distribute, and sell this software and its
  8.  * documentation for any purpose is hereby granted without fee, provided that
  9.  * the above copyright notice appears in all copies and that both that
  10.  * copyright notice and this permission notice appear in supporting
  11.  * documentation, and that the name of Lionel MALLET not be used in
  12.  * advertising or publicity pertaining to distribution of the software
  13.  * without specific, written prior permission.  Lionel MALLET makes no
  14.  * representations about the suitability of this software for any
  15.  * purpose.  It is provided "as is" without express or implied warranty.
  16.  *
  17.  * Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  18.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  19.  * FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
  20.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  21.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 
  22.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  23.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  *  This software is opened and free. Furthermore, everybody is kindly
  26.  * invited to participate to improve it for the benefit of all.
  27.  * Improvements can be new features, bugs fixes and porting issues
  28.  * resolution.
  29.  *
  30.  * Author:  Lionel Mallet, SIMULOG
  31.  */
  32.  
  33. /*
  34.  * $XConsortium: Handlers.c,v 1.1 90/06/09 20:20:35 dmatic Exp $
  35.  *
  36.  * Copyright 1989 Massachusetts Institute of Technology
  37.  *
  38.  * Permission to use, copy, modify, distribute, and sell this software and its
  39.  * documentation for any purpose is hereby granted without fee, provided that
  40.  * the above copyright notice appear in all copies and that both that
  41.  * copyright notice and this permission notice appear in supporting
  42.  * documentation, and that the name of M.I.T. not be used in advertising or
  43.  * publicity pertaining to distribution of the software without specific,
  44.  * written prior permission.  M.I.T. makes no representations about the
  45.  * suitability of this software for any purpose.  It is provided "as is"
  46.  * without express or implied warranty.
  47.  *
  48.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  49.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  50.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  51.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  52.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  53.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  54.  *
  55.  * Author:  Davor Matic, MIT X Consortium
  56.  */
  57.  
  58.  
  59.  
  60. #include <X11/IntrinsicP.h>
  61. #include <X11/Xmu/Converters.h>
  62. #include <X11/StringDefs.h>
  63. #include <X11/Xatom.h>
  64. #include <X11/Xos.h>
  65. #include "PixmapP.h"
  66.     
  67. #include <stdio.h>
  68. #include <math.h>
  69.  
  70. #define XtStrlen(s)                   ((s) ? strlen(s) : 0)
  71. #define abs(x)                        (((x) > 0) ? (x) : -(x))
  72. #define min(x, y)                     (((x) < (y)) ? (x) : (y))
  73. #define max(x, y)                     (((x) > (y)) ? (x) : (y))
  74.  
  75.  
  76. /*****************************************************************************
  77.  *                                  Handlers                                 *
  78.  *****************************************************************************/
  79.  
  80. #define QueryInSquare(PW, x, y, square_x, square_y)\
  81.     ((InPixmapX(PW, x) == (square_x)) &&\
  82.      (InPixmapY(PW, y) == (square_y)))
  83.  
  84.  
  85. void DragOnePointHandler(w, status, event)
  86.      Widget       w;
  87.      PWStatus    *status;
  88.      XEvent      *event;
  89. {
  90.     PixmapWidget PW = (PixmapWidget) w;
  91.  
  92.     if (_PWDEBUG)
  93.     fprintf(stderr, "D1PH ");
  94.  
  95.     switch (event->type) {
  96.     
  97.     case ButtonPress:
  98.     if (event->xbutton.state != status->state) return;
  99.     if (!QuerySet(status->at_x, status->at_y)) {
  100.         PWStoreToBuffer(w);
  101.         status->value = Value(PW, event->xbutton.button);
  102.         status->time = event->xbutton.time;
  103.         status->at_x = InPixmapX(PW, event->xbutton.x);
  104.         status->at_y = InPixmapY(PW, event->xbutton.y);
  105.         status->success = (status->draw != NULL);
  106.         if (status->draw)
  107.         (*status->draw)(w,
  108.                 status->at_x, status->at_y, status->value);
  109.     }
  110.     break;
  111.     
  112.     case ButtonRelease:
  113.     if (QuerySet(status->at_x, status->at_y)) {
  114.         status->value = Value(PW, event->xbutton.button);
  115.         status->time = event->xbutton.time;
  116.         status->at_x = InPixmapX(PW, event->xbutton.x);
  117.         status->at_y = InPixmapY(PW, event->xbutton.y);
  118.         status->success = (status->draw != NULL);
  119.       
  120.         PWTerminateRequest(w, TRUE);
  121.     }
  122.     break;
  123.  
  124.     case MotionNotify:
  125.     if (QuerySet(status->at_x, status->at_y)) {
  126.         if (!QueryInSquare(PW, event->xmotion.x, event->xmotion.y,
  127.                    status->at_x, status->at_y)) {
  128.         status->at_x = InPixmapX(PW, event->xmotion.x);
  129.         status->at_y = InPixmapY(PW, event->xmotion.y);
  130.         if (status->draw)
  131.             (*status->draw)(w,
  132.                     status->at_x, status->at_y, status->value);
  133.         }
  134.     }
  135.     break;
  136.  
  137.     }
  138. }
  139.  
  140. void DragOnePointEngage(w, status, draw, state)
  141.     Widget      w;
  142.     PWStatus   *status;
  143.     void      (*draw)();
  144.     int        *state;
  145. {
  146.     
  147.     status->at_x = NotSet;
  148.     status->at_y = NotSet;
  149.     status->draw = draw;
  150.     status->success = False;
  151.     status->state = *state;
  152.     
  153.     XtAddEventHandler(w,
  154.               ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  155.               FALSE, DragOnePointHandler, status);
  156. }
  157.  
  158. void DragOnePointTerminate(w, status, client_data, call_data)
  159.     Widget     w;
  160.     PWStatus  *status;
  161.     XtPointer    client_data, call_data;
  162. {
  163.     
  164.     if (status->success) {
  165.     PWChangeNotify(w, NULL, NULL);
  166.     PWSetChanged(w);
  167.     }
  168.     
  169.     XtRemoveEventHandler(w,
  170.          ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  171.          FALSE, DragOnePointHandler, status);
  172.     
  173. }
  174.  
  175. void OnePointHandler(w, status, event)
  176.     Widget       w;
  177.     PWStatus    *status;
  178.     XEvent      *event;
  179. {
  180.     PixmapWidget PW = (PixmapWidget) w;
  181.     
  182.     if (_PWDEBUG)
  183.     fprintf(stderr, "1PH ");
  184.  
  185.     switch (event->type) {
  186.     
  187.     case Expose:
  188.     if (QuerySet(status->at_x, status->at_y)) {
  189.         PWClip(w, 
  190.            InPixmapX(PW, event->xexpose.x), 
  191.            InPixmapY(PW, event->xexpose.y),
  192.            InPixmapX(PW, event->xexpose.x + event->xexpose.width),
  193.            InPixmapY(PW, event->xexpose.y + event->xexpose.height));
  194.         if (status->draw)
  195.         (*status->draw)(w,
  196.                 status->at_x, status->at_y, Highlight);
  197.         
  198.         PWUnclip(w);
  199.     }
  200.     break;
  201.     
  202.     case ButtonPress:
  203.     if (event->xbutton.state != status->state) return;
  204.     if (!QuerySet(status->at_x, status->at_y)) {
  205.         status->value = Value(PW, event->xbutton.button);
  206.         status->time = event->xbutton.time;
  207.         status->at_x = InPixmapX(PW, event->xbutton.x);
  208.         status->at_y = InPixmapY(PW, event->xbutton.y);
  209.         if (status->draw)
  210.         (*status->draw)(w,
  211.                 status->at_x, status->at_y, Highlight);
  212.     }
  213.     break;
  214.     
  215.     case ButtonRelease:
  216.     if (QuerySet(status->at_x, status->at_y)) {
  217.         if (status->draw)
  218.         (*status->draw)(w,
  219.                 status->at_x, status->at_y, Highlight);
  220.         
  221.         /* the following 3 lines is a small fix to Ctrl ops */
  222.         if (event->xbutton.state&ControlMask)
  223.           status->value = Set;
  224.         else status->value = Value(PW, event->xbutton.button);
  225.  
  226.         status->time = event->xbutton.time;
  227.         status->at_x = InPixmapX(PW, event->xbutton.x);
  228.         status->at_y = InPixmapY(PW, event->xbutton.y);
  229.         status->success = True;
  230.         
  231.         PWTerminateRequest(w, TRUE);
  232.     }
  233.     break;
  234.     
  235.     case MotionNotify:
  236.     if (QuerySet(status->at_x, status->at_y)) {
  237.         if (!QueryInSquare(PW, event->xmotion.x, event->xmotion.y,
  238.                    status->at_x, status->at_y)) {
  239.         if (status->draw)
  240.             (*status->draw)(w,
  241.                     status->at_x, status->at_y, Highlight);
  242.         status->at_x = InPixmapX(PW, event->xmotion.x);
  243.         status->at_y = InPixmapY(PW, event->xmotion.y);
  244.         if (status->draw)
  245.             (*status->draw)(w,
  246.                     status->at_x, status->at_y, Highlight);
  247.         }
  248.     }      
  249.     break;
  250.     }
  251. }
  252.  
  253. void OnePointEngage(w, status, draw, state)
  254.     Widget      w;
  255.     PWStatus   *status;
  256.     void      (*draw)();
  257.     int        *state;
  258. {
  259.     status->at_x = NotSet;
  260.     status->at_y = NotSet;
  261.     status->draw = draw;
  262.     status->success = False;
  263.     status->state = *state;
  264.  
  265.     XtAddEventHandler(w,
  266.               ButtonPressMask | ButtonReleaseMask | 
  267.               ExposureMask | PointerMotionMask,
  268.               FALSE, OnePointHandler, status);
  269. }
  270.  
  271. void OnePointImmediateEngage(w, status, draw, state)
  272.     Widget      w;
  273.     PWStatus   *status;
  274.     void      (*draw)();
  275.     int        *state;
  276. {
  277.     status->at_x = 0;
  278.     status->at_y = 0;
  279.     status->draw = draw;
  280.     status->success = False;
  281.     status->state = *state;
  282.     
  283.     if (status->draw)
  284.     (*status->draw)(w,
  285.             status->at_x, status->at_y, Highlight);
  286.     
  287.     XtAddEventHandler(w,
  288.               ButtonPressMask | ButtonReleaseMask | 
  289.               ExposureMask | PointerMotionMask,
  290.               FALSE, OnePointHandler, status);
  291. }
  292.  
  293. void OnePointTerminate(w, status, draw)
  294.     Widget     w;
  295.     PWStatus  *status;
  296.     void     (*draw)();
  297. {
  298.     
  299.     if (status->success && draw) {
  300.     PWStoreToBuffer(w);
  301.     (*draw)(w,
  302.         status->at_x, status->at_y,
  303.         status->value);
  304.     PWChangeNotify(w, NULL, NULL);
  305.     PWSetChanged(w);
  306.     }    
  307.     else
  308.     if (QuerySet(status->at_x, status->at_y))
  309.         if (status->draw)
  310.         (*status->draw)(w,
  311.                 status->at_x, status->at_y, Highlight);
  312.     
  313.     XtRemoveEventHandler(w,
  314.              ButtonPressMask | ButtonReleaseMask | 
  315.              ExposureMask | PointerMotionMask,
  316.              FALSE, OnePointHandler, status);
  317. }
  318.  
  319. void OnePointTerminateTransparent(w, status, draw)
  320.     Widget     w;
  321.     PWStatus  *status;
  322.     void     (*draw)();
  323. {
  324.     
  325.     if (status->success && draw)
  326.     (*draw)(w,
  327.         status->at_x, status->at_y,
  328.         status->value);
  329.     else
  330.     if (QuerySet(status->at_x, status->at_y))
  331.         if (status->draw)
  332.         (*status->draw)(w,
  333.                 status->at_x, status->at_y, Highlight);
  334.     
  335.     XtRemoveEventHandler(w,
  336.              ButtonPressMask | ButtonReleaseMask | 
  337.              ExposureMask | PointerMotionMask,
  338.              FALSE, OnePointHandler, status);
  339.     
  340. }
  341.  
  342.  
  343. void TwoPointsHandler(w, status, event)
  344.     Widget      w;
  345.     PWStatus   *status;
  346.     XEvent     *event;
  347. {
  348.     PixmapWidget PW = (PixmapWidget) w;
  349.  
  350.     if (_PWDEBUG)
  351.     fprintf(stderr, "2PH ");
  352.     
  353.     switch (event->type) {
  354.     
  355.     case Expose:
  356.     if (QuerySet(status->from_x, status->from_y) && 
  357.         QuerySet(status->to_x, status->to_y)) {
  358.         PWClip(w, 
  359.            InPixmapX(PW, event->xexpose.x), 
  360.            InPixmapY(PW, event->xexpose.y),
  361.            InPixmapX(PW, event->xexpose.x + event->xexpose.width),
  362.            InPixmapY(PW, event->xexpose.y + event->xexpose.height));
  363.         if (status->draw)
  364.         (*status->draw)(w,
  365.                 status->from_x, status->from_y, 
  366.                 status->to_x, status->to_y, Highlight);
  367.         PWUnclip(w);
  368.     }
  369.     break;
  370.     
  371.     case ButtonPress:
  372.     if (event->xbutton.state != status->state) return;
  373.     if (!QuerySet(status->from_x, status->from_y)) {
  374.         status->value = Value(PW, event->xbutton.button);
  375.         status->time = event->xbutton.time;
  376.         status->from_x = InPixmapX(PW, event->xbutton.x);
  377.         status->from_y = InPixmapY(PW, event->xbutton.y);
  378.         status->to_x = InPixmapX(PW, event->xbutton.x);
  379.         status->to_y = InPixmapY(PW, event->xbutton.y);
  380.         if (status->draw)
  381.         (*status->draw)(w,
  382.                 status->from_x, status->from_y, 
  383.                 status->to_x, status->to_y, Highlight);
  384.     }
  385.     break;
  386.     
  387.     case ButtonRelease:
  388.     if (QuerySet(status->from_x, status->from_y)) {
  389.         if (status->draw)
  390.         (*status->draw)(w,
  391.                 status->from_x, status->from_y, 
  392.                 status->to_x, status->to_y, Highlight);
  393.         status->value = Value(PW, event->xbutton.button);
  394.         status->time = event->xbutton.time;        
  395.         status->to_x = InPixmapX(PW, event->xbutton.x);
  396.         status->to_y = InPixmapY(PW, event->xbutton.y);
  397.         status->success = True;
  398.         
  399.         PWTerminateRequest(w, TRUE);
  400.     }
  401.     break;
  402.     
  403.     case MotionNotify:
  404.     if (QuerySet(status->from_x, status->from_y)) {
  405.         if (QuerySet(status->to_x, status->to_y)) {
  406.         if (!QueryInSquare(PW, event->xmotion.x, event->xmotion.y,
  407.                    status->to_x, status->to_y)) {
  408.             if (status->draw)
  409.             (*status->draw)(w,
  410.                     status->from_x, status->from_y, 
  411.                     status->to_x, status->to_y, Highlight);
  412.             status->to_x = InPixmapX(PW, event->xmotion.x);
  413.             status->to_y = InPixmapY(PW, event->xmotion.y);
  414.             if (status->draw)
  415.             (*status->draw)(w,
  416.                     status->from_x, status->from_y, 
  417.                     status->to_x, status->to_y, Highlight);
  418.         }
  419.         }
  420.         else {
  421.         status->to_x = InPixmapX(PW, event->xmotion.x);
  422.         status->to_y = InPixmapY(PW, event->xmotion.y);
  423.         if (status->draw)
  424.             (*status->draw)(w,
  425.                     status->from_x, status->from_y, 
  426.                     status->to_x, status->to_y, Highlight);
  427.         }
  428.     }
  429.     break;
  430.     }
  431. }
  432.  
  433. void TwoPointsEngage(w, status, draw, state)
  434.     Widget     w;
  435.     PWStatus  *status;
  436.     void     (*draw)();
  437.     int       *state;
  438. {
  439.     
  440.     status->from_x = NotSet;
  441.     status->from_y = NotSet;
  442.     status->to_x = NotSet;
  443.     status->to_y = NotSet;
  444.     status->draw = draw;
  445.     status->success = False;
  446.     status->state = *state;
  447.  
  448.     XtAddEventHandler(w,
  449.               ButtonPressMask | ButtonReleaseMask | 
  450.               ExposureMask | PointerMotionMask,
  451.               FALSE, TwoPointsHandler, status);
  452. }
  453.  
  454. void TwoPointsTerminate(w, status, draw)
  455.     Widget    w;
  456.     PWStatus *status;
  457.     void    (*draw)();
  458. {
  459.     
  460.     if (status->success && draw) {
  461.     PWStoreToBuffer(w);
  462.     (*draw)(w,
  463.         status->from_x, status->from_y,
  464.         status->to_x, status->to_y,
  465.         status->value);
  466.     PWChangeNotify(w, NULL, NULL);
  467.     PWSetChanged(w);
  468.     }
  469.     else
  470.     if (QuerySet(status->from_x, status->from_y) && 
  471.         QuerySet(status->to_x, status->to_y))
  472.         if (status->draw)
  473.         (*status->draw)(w,
  474.                 status->from_x, status->from_y, 
  475.                 status->to_x, status->to_y, Highlight);
  476.     
  477.     XtRemoveEventHandler(w,
  478.              ButtonPressMask | ButtonReleaseMask | 
  479.              ExposureMask | PointerMotionMask,
  480.              FALSE, TwoPointsHandler, status);
  481. }
  482.  
  483. void TwoPointsTerminateTransparent(w, status, draw)
  484.     Widget    w;
  485.     PWStatus *status;
  486.     void    (*draw)();
  487. {
  488.     
  489.     if (status->success && draw)
  490.     (*draw)(w,
  491.         status->from_x, status->from_y,
  492.         status->to_x, status->to_y,
  493.         status->value);
  494.     else
  495.     if (QuerySet(status->from_x, status->from_y) && 
  496.         QuerySet(status->to_x, status->to_y))
  497.         if (status->draw)
  498.         (*status->draw)(w,
  499.                 status->from_x, status->from_y, 
  500.                 status->to_x, status->to_y, Highlight);
  501.     
  502.     XtRemoveEventHandler(w,
  503.              ButtonPressMask | ButtonReleaseMask | 
  504.              ExposureMask | PointerMotionMask,
  505.              FALSE, TwoPointsHandler, status);
  506. }
  507.  
  508. void TwoPointsTerminateTimed(w, status, draw)
  509.     Widget    w;
  510.     PWStatus *status;
  511.     void    (*draw)();
  512. {
  513.     
  514.     if (status->success && draw)
  515.     (*draw)(w,
  516.         status->from_x, status->from_y,
  517.         status->to_x, status->to_y,
  518.         status->time);
  519.     else
  520.     if (QuerySet(status->from_x, status->from_y) && 
  521.         QuerySet(status->to_x, status->to_y))
  522.         if (status->draw)
  523.         (*status->draw)(w,
  524.                 status->from_x, status->from_y, 
  525.                 status->to_x, status->to_y, Highlight);
  526.     
  527.     XtRemoveEventHandler(w,
  528.              ButtonPressMask | ButtonReleaseMask | 
  529.              ExposureMask | PointerMotionMask,
  530.              FALSE, TwoPointsHandler, status);
  531. }
  532.  
  533. void Interface(w, status, action)
  534.     Widget     w;
  535.     XtPointer    status;
  536.     void     (*action)();
  537. {
  538.      (*action)(w);
  539. }
  540.  
  541. void Paste(w, at_x, at_y, value)
  542.     Widget    w;
  543.     Position  at_x, at_y;
  544.     int       value;
  545. {
  546.     PixmapWidget    PW = (PixmapWidget) w;
  547.     PWStatus       *my_status;
  548.     PWRequest       request;
  549.  
  550.     my_status = (PWStatus *) 
  551.     PW->pixmap.request_stack[PW->pixmap.current].status;
  552.  
  553.     my_status->draw = NULL;
  554.  
  555.    request = (PWRequest)
  556.    PW->pixmap.request_stack[PW->pixmap.current].request->terminate_client_data;
  557.     
  558.     PWTerminateRequest(w, FALSE);
  559.     
  560.     if ((at_x == max(PW->pixmap.mark.from_x, min(at_x, PW->pixmap.mark.to_x)))
  561.     &&
  562.       (at_y == max(PW->pixmap.mark.from_y, min(at_y, PW->pixmap.mark.to_y)))) {
  563.     
  564.     PWStatus *status;
  565.     
  566.     if (_PWDEBUG)
  567.         fprintf(stderr, "Prepaste request: %s\n", request);
  568.     
  569.     PWEngageRequest(w, request, False, (XtPointer)&(my_status->state), 
  570.             (Cardinal)sizeof(int));
  571.     
  572.     status = (PWStatus *) 
  573.         PW->pixmap.request_stack[PW->pixmap.current].status;
  574.     
  575.     status->at_x = at_x;
  576.     status->at_y = at_y;
  577.     status->value = value;
  578.     (*status->draw) (w, at_x, at_y, Highlight);    
  579.     }
  580.     else {
  581.  
  582.     PWStatus *status;
  583.     
  584.       PWEngageRequest(w, MarkRequest, False, (XtPointer)&(my_status->state), 
  585.               (Cardinal)sizeof(int));
  586.     
  587.     status = (PWStatus *) 
  588.         PW->pixmap.request_stack[PW->pixmap.current].status;
  589.     
  590.     status->from_x = status->to_x = at_x;
  591.     status->from_y = status->to_y = at_y;
  592.     status->value = value;
  593.     (*status->draw) (w, at_x, at_y, at_x, at_y, Highlight);
  594.     }
  595. }
  596.  
  597.  
  598. void DragTwoPointsHandler(w, status, event)
  599.     Widget      w;
  600.     PWStatus   *status;
  601.     XEvent     *event;
  602. {
  603.     PixmapWidget PW = (PixmapWidget) w;
  604.  
  605.     if (_PWDEBUG)
  606.     fprintf(stderr, "D2PH ");
  607.  
  608.     switch (event->type) {
  609.     
  610.     case ButtonPress:
  611.     if (event->xbutton.state != status->state) return;
  612.     if (!QuerySet(status->from_x, status->from_y)) {
  613.         PWStoreToBuffer(w);
  614.         status->value = Value(PW, event->xbutton.button);
  615.         status->time = event->xbutton.time;
  616.         status->from_x = InPixmapX(PW, event->xbutton.x);
  617.         status->from_y = InPixmapY(PW, event->xbutton.y);
  618.         status->to_x = InPixmapX(PW, event->xbutton.x);
  619.         status->to_y = InPixmapY(PW, event->xbutton.y);
  620.         status->success = (status->draw != NULL);
  621.         if (status->draw)
  622.         (*status->draw)(w,
  623.                 status->from_x, status->from_y, 
  624.                 status->to_x, status->to_y, status->value);
  625.     }
  626.     break;
  627.     
  628.     case ButtonRelease:
  629.     if (QuerySet(status->from_x, status->from_y)) {
  630.         status->value = Value(PW, event->xbutton.button);
  631.         status->time = event->xbutton.time;        
  632.         status->from_x = status->to_x;
  633.         status->from_y = status->to_y;
  634.         status->to_x = InPixmapX(PW, event->xbutton.x);
  635.         status->to_y = InPixmapY(PW, event->xbutton.y);
  636.         status->success = True;
  637.         
  638.         PWTerminateRequest(w, TRUE);
  639.     }
  640.     break;
  641.     
  642.     case MotionNotify:
  643.     if (QuerySet(status->from_x, status->from_y)) {
  644.         if (QuerySet(status->to_x, status->to_y)) {
  645.         if (!QueryInSquare(PW, event->xmotion.x, event->xmotion.y,
  646.                    status->to_x, status->to_y)) {
  647.             status->from_x = status->to_x;
  648.             status->from_y = status->to_y;
  649.             status->to_x = InPixmapX(PW, event->xmotion.x);
  650.             status->to_y = InPixmapY(PW, event->xmotion.y);
  651.             if (status->draw)
  652.             (*status->draw)(w,
  653.                     status->from_x, status->from_y, 
  654.                     status->to_x, status->to_y, status->value);
  655.         }
  656.         }
  657.     }
  658.     break;
  659.     }
  660. }
  661.  
  662. void DragTwoPointsEngage(w, status, draw, state)
  663.     Widget     w;
  664.     PWStatus  *status;
  665.     void     (*draw)();
  666.     int       *state;
  667. {
  668.     
  669.     status->from_x = NotSet;
  670.     status->from_y = NotSet;
  671.     status->to_x = NotSet;
  672.     status->to_y = NotSet;
  673.     status->draw = draw;
  674.     status->success = False;
  675.     status->state = *state;
  676.  
  677.     XtAddEventHandler(w,
  678.               ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  679.               FALSE, DragTwoPointsHandler, status);
  680. }
  681.  
  682. void DragTwoPointsTerminate(w, status, draw)
  683.     Widget     w;
  684.     PWStatus  *status;
  685.     void     (*draw)();
  686. {
  687.     
  688.     if (status->success && draw) {
  689.     if ((status->from_x != status->to_x) 
  690.         || 
  691.         (status->from_y != status->to_y))
  692.         (*draw)(w,
  693.             status->from_x, status->from_y,
  694.             status->to_x, status->to_y,
  695.             status->value);
  696.     PWChangeNotify(w, NULL, NULL);
  697.     PWSetChanged(w);
  698.     }
  699.     
  700.     XtRemoveEventHandler(w,
  701.                  ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  702.              FALSE, DragTwoPointsHandler, status);
  703. }
  704.  
  705.  
  706. void PWTPaste(w, event)
  707.     Widget  w;
  708.     XEvent *event;
  709. {
  710.     PixmapWidget PW = (PixmapWidget) w;
  711.  
  712.     if (!PW->pixmap.selection.own)
  713.     PWRequestSelection(w, event->xbutton.time, TRUE);
  714.     else 
  715.     PWStore(w);
  716.  
  717.     if (!PWQueryStored(w))
  718.     return;
  719.  
  720.     PWEngageRequest(w, RestoreRequest, False, 
  721.             (XtPointer)&(event->xbutton.state), (Cardinal)sizeof(int));
  722.     
  723.     OnePointHandler(w,
  724.            (PWStatus*) PW->pixmap.request_stack[PW->pixmap.current].status,
  725.            event);
  726. }
  727.  
  728. void PWTMark(w, event)
  729.     Widget  w;
  730.     XEvent *event;
  731. {
  732.     PixmapWidget PW = (PixmapWidget) w;
  733.  
  734.     PWEngageRequest(w, MarkRequest, False,
  735.             (XtPointer)&(event->xbutton.state), (Cardinal)sizeof(int));
  736.     TwoPointsHandler(w,
  737.             (PWStatus*) PW->pixmap.request_stack[PW->pixmap.current].status,
  738.          event);
  739. }
  740.  
  741. void PWTUnmark(w)
  742.     Widget w;
  743. {
  744.     PWUnmark(w);
  745. }
  746.  
  747.  
  748. /*****************************************************************************/
  749.